import { ObjectWrap } from './../../../Core/FrameEx/ES5Ex';
import { JXBtlArrIx } from './JXBattleDefine';
import JXRBCmdMgr from "./JXRBCmdMgr";
import { JXRBRole } from "./JXRBRole";
import { COMMON_ANI_NAME, JXBattleSkillSpine, JXBuffOrderThreshold, JXCollisionRoot, JXRB_ROLE_LAYER_NAME } from './JXULDefine';

export class JXRBCollisionEffect extends ObjectWrap {
    protected _collisionRaw: SActionCollisionRaw = null;
    public target: JXRBRole;

    protected colisionFrames: cc.Node[] = [];
    protected _cmd: JXRBCmdMgr = null;

    constructor(collisionRaw: SActionCollisionRaw, cmd: JXRBCmdMgr) {
        super();
        this._collisionRaw = collisionRaw;
        this._cmd = cmd;
    }

    public get offsets(): cc.Vec2[] {
        let offsets = [];
        for (let i = 0; i < this._collisionRaw.position.length; i++) {
            offsets.push(cc.v2(this._collisionRaw.position[i][JXBtlArrIx.Zero] || 0, this._collisionRaw.position[i][JXBtlArrIx.One] || 0))
        }
        return offsets;
    }

    /**加载对应的动画图集 */
    public loadFrames(aniConfig: any[], isEvent?: boolean): cc.Node {
        let animation = this._cmd.assetManager.createEffect(aniConfig as any, JXCollisionRoot, cc.WrapMode.Normal);
        if (isEvent) {
            animation.once(cc.Animation.EventType.FINISHED, this.onAnimationEnd, this);
        }
        animation.play(COMMON_ANI_NAME);
        return animation.node;
    }

    public loadSpine(aniConfig: any[], isEvent?: boolean) {
        let node = new cc.Node();
        let sk = node.addComponent(sp.Skeleton);
        sk.premultipliedAlpha = !!aniConfig[JXBtlArrIx.Four];
        let skData = this._cmd.assetManager.assetImpl.getPreLoadAsset<sp.SkeletonData>(JXBattleSkillSpine + aniConfig[JXBtlArrIx.Zero]);
        sk.skeletonData = skData;
        node.scale = aniConfig[JXBtlArrIx.Five];
        node.anchorY = 0;
        node.opacity = aniConfig[JXBtlArrIx.Six] * 255;
        if (isEvent) {
            sk.setCompleteListener(this.onAnimationEnd.bind(this));
        }
        return sk.node;
    }

    public addToTarget(role: JXRBRole) {
        this.target = role;
        let offsets = this.offsets;
        let visiLayer = this._collisionRaw.visFirst;
        for (let i = 0; i < this._collisionRaw.effect.length; i++) {
            let child = null;
            if (this._collisionRaw.isSpine) {
                child = this.loadSpine(this._collisionRaw.effect[i], i == JXBtlArrIx.Zero);

            } else {
                child = this.loadFrames(this._collisionRaw.effect[i], i == JXBtlArrIx.Zero);
            }
            child.position = offsets[i];

            if (visiLayer[i] < JXBuffOrderThreshold) {
                let layer = role.target.getChildByName(JXRB_ROLE_LAYER_NAME.LOWER);
                child.parent = layer;
            }
            else {
                let layer = role.target.getChildByName(JXRB_ROLE_LAYER_NAME.UPPER);
                child.parent = layer;
            }
            if (this._collisionRaw.isSpine) {
                let sk: sp.Skeleton = child.getComponent(sp.Skeleton);
                sk.timeScale = 1.4;
                sk.setAnimation(0, this._collisionRaw.effect[i][JXBtlArrIx.One], false);
            }
            child.x *= this.target.dir;
            child.scaleX *= this.target.dir;
            child.zIndex = visiLayer[i];
            this.colisionFrames.push(child);
        }

        if (this._collisionRaw.state) {
            let target = this.target, state = this._collisionRaw.state;
            target.addAction(cc.callFunc(() => {
                target.changeState(state);
            }))
        }

    }

    public onAnimationEnd() {
        for (let i = 0; i < this.colisionFrames.length; i++) {
            this.colisionFrames[i].destroy();
        }
        this.colisionFrames.length = 0;
        this.colisionFrames = null;
        this._collisionRaw = null;
        this.target = null;
    }
}